package root.electronclass.electronclass.common.base

import android.annotation.SuppressLint
import android.app.Activity
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.fragment.app.DialogFragment
import androidx.viewbinding.ViewBinding
import root.electronclass.electronclass.R
import root.electronclass.electronclass.databinding.DialogBasicBinding
import root.electronclass.electronclass.ext.inflateMethod
import java.lang.reflect.ParameterizedType


/**
 *
 * @author Lokiy
 * @date 2023/2/18 14:28
 */
open class BasicDialogFragment<T : ViewBinding> : DialogFragment() {

    private val bindingClass by lazy { (this::class.java.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<*> }
    lateinit var parentBinding: DialogBasicBinding
        private set
    lateinit var binding: T
        private set

    var onOkClick: (View) -> Unit = {}
    var onCancelClick: (View) -> Unit = { dismiss() }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setStyle(STYLE_NO_TITLE, R.style.CustomDialog)
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        parentBinding = DialogBasicBinding.inflate(inflater, container, false)
        val root = parentBinding.root

        @Suppress("UNCHECKED_CAST")
        val child = (bindingClass.inflateMethod.invoke(this, layoutInflater, root, false) as T).also { binding = it }.root
        if (child.layoutParams.width > 0) {
            updateDialogWidth(child.layoutParams.width)
        }
        parentBinding.dialogContainer.addView(child)
        updateDialogHeight(child.layoutParams.height)
        parentBinding.title.text = arguments?.getString(TITLE)

        parentBinding.save.text = arguments?.getString(OK) ?: "".also { parentBinding.save.isVisible = false }
        parentBinding.save.setOnClickListener {
            onOkClick.invoke(it)
        }

        parentBinding.cancel.setOnClickListener {
            onCancelClick.invoke(it)
        }

        parentBinding.close.isVisible = arguments?.getBoolean(CLOSE, false)?.also {
            parentBinding.close.setOnClickListener { dismiss() }
        } ?: false


        return root
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog = super.onCreateDialog(savedInstanceState)
        dialog.apply {
            // 设置全屏，隐藏状态栏和导航栏
            val window = window ?: return@apply
            window.decorView.systemUiVisibility =
                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
                        View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
                        View.SYSTEM_UI_FLAG_FULLSCREEN or
                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
                        View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
            window.statusBarColor = android.graphics.Color.TRANSPARENT
        }
        dialog.setOnShowListener {
            val decorView = dialog.window!!.decorView
            decorView.setOnTouchListener { v: View?, event: MotionEvent ->
                if (event.action == MotionEvent.ACTION_UP) {
                    hideKeyboard()
                }
                true
            }
        }
        return dialog
    }

    /**
     * 设置title
     */
    fun setTitle(title: String, tag: String) {
        parentBinding.title.text = title
        if (tag.isNotEmpty()) {
            parentBinding.dialogTag.text = tag
        }

    }

    private fun hideKeyboard() {
        val imm = activity?.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
        val view = activity?.currentFocus
        if (view != null) {
            imm.hideSoftInputFromWindow(view.windowToken, 0)
        }
    }

    fun updateDialogHeight(height: Int) {
        if (height > 0) {
            binding.root.updateLayoutParams<ViewGroup.LayoutParams> {
                this.height = -2
            }
            parentBinding.dialogContainer.updateLayoutParams<ViewGroup.LayoutParams> {
                this.height = height
            }
        }
    }

    fun updateDialogWidth(width: Int) {
        if (width > 0) {
            binding.root.updateLayoutParams<ViewGroup.LayoutParams> {
                this.width = -2
            }
            parentBinding.dialogLayout.updateLayoutParams<ViewGroup.LayoutParams> {
                this.width = width
            }
        }
    }

    override fun onStart() {
        super.onStart()
        dialog?.window?.setLayout(-1, -1)
    }

    companion object {
        const val TITLE = "_TITLE"
        const val OK = "_OK"
        const val CANCEL = "_CANCEL"
        const val CLOSE = "_CLOSE"
        const val bg = "bg"
    }
}
